package com.briup.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.briup.common.response.ResultCode;
import com.briup.common.utils.AssertUtil;
import com.briup.server.domain.bean.Labs;
import com.briup.server.domain.bean.LabsAdminR;
import com.briup.server.domain.bean.User;
import com.briup.server.domain.dto.LabsAssignAdminDTO;
import com.briup.server.mapper.LabsAdminRMapper;
import com.briup.server.service.LabsAdminRService;
import com.briup.server.service.LabsService;
import com.briup.server.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;

@Service
@RequiredArgsConstructor
public class LabsAdminRServiceImpl extends ServiceImpl<LabsAdminRMapper, LabsAdminR>
        implements LabsAdminRService {

    private final UserService userService;
    private final LabsService labsService;

    @Override
    public List<User> queryListEnabled() {
        // 查询所有的实验室管理员列表
        List<User> users = userService.labsAdminList();
        LambdaQueryWrapper<LabsAdminR> wrapper = Wrappers.<LabsAdminR>lambdaQuery()
                .select(LabsAdminR::getAdminId);
        // 查询当前已经本绑定的实验室管理员的用户id
        List<Long> adminIds = baseMapper.selectList(wrapper).stream()
                .map(LabsAdminR::getAdminId).distinct().toList();
        // 过滤出当前还未分配实验室的实验室管理员用户
        return users.stream()
                .filter(user -> !adminIds.contains(user.getId()))
                .toList();
    }

    @Transactional
    @Override
    public void assignAdmin(LabsAssignAdminDTO assignAdminDTO) {
        // 查看实验室是否存在
        Labs labs = labsService.getById(assignAdminDTO.getLabId());
        AssertUtil.notNull(labs, ResultCode.LABS_IS_NOT_EXISTS);
        // 在保存数据之前，先删除该实验室已经绑定的所有实验室管理员关系
        remove(Wrappers.<LabsAdminR>lambdaQuery()
                .eq(LabsAdminR::getLabsId, assignAdminDTO.getLabId()));

        // 查看管理员是否存在
        List<User> admins = userService.listByIds(assignAdminDTO.getAdminId());
        AssertUtil.isTrue(!CollectionUtils.isEmpty(admins)
                          && admins.size() == assignAdminDTO.getAdminId().size(),
                ResultCode.USER_IS_NOT_EXISTS);
        // 查看该实验室管理员是否已经关联了其他实验室
        LambdaQueryWrapper<LabsAdminR> wrapper = Wrappers.<LabsAdminR>lambdaQuery()
                .select(LabsAdminR::getLabsId)
                // 查询出所有绑定了该实验室管理员的实验室id
                .in(LabsAdminR::getAdminId, assignAdminDTO.getAdminId());
        List<LabsAdminR> labsIss = baseMapper.selectList(wrapper);
        AssertUtil.isTrue(labsIss.isEmpty(), ResultCode.USER_HAS_ASSIGNED_LABS);

        // 关联实验室管理员和实验室
        List<LabsAdminR> list = assignAdminDTO.getAdminId()
                .stream()
                .map(adminId -> this.buildLabsAdminR(assignAdminDTO.getLabId(), adminId))
                .toList();
        // 批量保存关联关系
        saveBatch(list);
    }

    @Override
    public List<User> queryAdmins(String id) {
        // 构建查询列表，查询所有绑定了该实验室的管理员id
        LambdaQueryWrapper<LabsAdminR> wrapper = Wrappers.<LabsAdminR>lambdaQuery()
                .select(LabsAdminR::getAdminId)
                .eq(LabsAdminR::getLabsId, id);
        List<Long> adminIds = baseMapper.selectList(wrapper).stream()
                .map(LabsAdminR::getAdminId)
                .toList();
        // 根据用户id查询对应用户，如果用户id列表为空，则返回空列表
        if (CollectionUtils.isEmpty(adminIds)) {
            return List.of();
        }
        return userService.listByIds(adminIds);
    }

    private LabsAdminR buildLabsAdminR(String labId, Long adminId) {
        LabsAdminR labsAdminR = new LabsAdminR();
        labsAdminR.setLabsId(labId);
        labsAdminR.setAdminId(adminId);
        return labsAdminR;
    }
}




